package com.lupengning.payment.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lupengning.payment.entity.OrderInfo;
import com.lupengning.payment.entity.Product;
import com.lupengning.payment.enums.OrderStatus;
import com.lupengning.payment.mapper.OrderInfoMapper;
import com.lupengning.payment.mapper.ProductMapper;
import com.lupengning.payment.service.OrderInfoService;
import com.lupengning.payment.util.OrderNoUtils;
import java.time.Duration;
import java.time.Instant;
import java.util.List;
import java.util.Objects;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Slf4j
@Service
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements
    OrderInfoService {

  @Resource
  private ProductMapper productMapper;

  @Resource
  private OrderInfoMapper orderInfoMapper;

  /**
   * 保存订单信息
   *
   * @param productId
   * @return
   */
  @Override
  public OrderInfo createOrderByProductId(Long productId) {

    //查找已存在但未支付的订单
    OrderInfo orderInfo = this.getNoPayOrderByProductId(productId);
    if (orderInfo != null) {
      return orderInfo;
    }

    //获取商品信息
    Product product = productMapper.selectById(productId);
    //生成订单
    orderInfo = new OrderInfo();
    orderInfo.setTitle(product.getTitle());
    //订单号
    orderInfo.setOrderNo(OrderNoUtils.getOrderNo());
    orderInfo.setProductId(productId);
    //分
    orderInfo.setTotalFee(product.getPrice());
    orderInfo.setOrderStatus(OrderStatus.NOTPAY.getType());
    baseMapper.insert(orderInfo);
    return orderInfo;
  }

  /**
   * 存储二维码
   *
   * @param orderNo
   * @param codeUrl
   */
  @Override
  public void saveCodeUrl(String orderNo, String codeUrl) {
    log.info("订单未存在，保存二维码。。。");
    UpdateWrapper<OrderInfo> updateWrapper = new UpdateWrapper<>();
    updateWrapper.eq("order_no", orderNo);
    OrderInfo orderInfo = new OrderInfo();
    orderInfo.setCodeUrl(codeUrl);
    baseMapper.update(orderInfo, updateWrapper);
  }

  /**
   * 订单列表按照创建时间倒序输出
   *
   * @return
   */
  @Override
  public List<OrderInfo> listOrderByCreateTimeDesc() {
    LambdaQueryWrapper<OrderInfo> infoQueryWrapper = new LambdaQueryWrapper<>();
    infoQueryWrapper.orderByDesc(OrderInfo::getCreateTime);
    return baseMapper.selectList(infoQueryWrapper);
  }

  /**
   * 更新订单状态
   *
   * @param orderNo
   * @param orderStatus
   */
  @Transactional(rollbackFor = Exception.class)
  @Override
  public void updateStatusByOrderNo(String orderNo, OrderStatus orderStatus) {
    log.info("更新订单状态");

    LambdaUpdateWrapper<OrderInfo> orderInfoUpdateWrapper = new LambdaUpdateWrapper<>();
    orderInfoUpdateWrapper.eq(OrderInfo::getOrderNo, orderNo);
    OrderInfo orderInfo = OrderInfo.builder().orderStatus(orderStatus.getType()).build();
    orderInfoMapper.update(orderInfo, orderInfoUpdateWrapper);
  }

  @Override
  public String getOrderStatus(String orderNo) {

    LambdaQueryWrapper<OrderInfo> queryWrapper = new LambdaQueryWrapper<>();
    OrderInfo orderInfo = baseMapper.selectOne(queryWrapper.eq(OrderInfo::getOrderNo, orderNo));
    if (Objects.isNull(orderInfo)) {
      return null;
    }
    return orderInfo.getOrderStatus();
  }

  /**
   * 找出创建超过minutes分钟并且未支付的订单
   * @param minutes
   * @return
   */
  @Override
  public List<OrderInfo> getNoPayOrderByDuration(int minutes) {

    //minutes分钟之前的时间
    Instant instant = Instant.now().minus(Duration.ofMinutes(minutes));
    QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("order_status", OrderStatus.NOTPAY.getType());
    queryWrapper.le("create_time", instant);
    List<OrderInfo> orderInfoList = baseMapper.selectList(queryWrapper);
    return orderInfoList;
  }

  /**
   * 根据订单号获取订单
   * @param orderNo
   * @return
   */
  @Override
  public OrderInfo getOrderByOrderNo(String orderNo) {
    QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("order_no", orderNo);
    OrderInfo orderInfo = baseMapper.selectOne(queryWrapper);
    return orderInfo;
  }

  /**
   * 查找已存在但未支付的订单
   *
   * @param productId
   * @return
   */
  private OrderInfo getNoPayOrderByProductId(Long productId) {
    QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("product_id", productId);
    queryWrapper.eq("order_status", OrderStatus.NOTPAY.getType());
    OrderInfo orderInfo = baseMapper.selectOne(queryWrapper);
    return orderInfo;
  }
}
